using System;
using ThunderRoad;
using UnityEngine;
using UnityEngine.Events;

namespace BBYScripts
{
    public class SwordBlink : MonoBehaviour
    {
        // 握剑手
        [Tooltip("握剑手")] public Side handleSide = Side.Right;

        // 瞬移音效
        [Tooltip("瞬移音效")] public AudioSource blinkAudioSource;

        // 剑回
        [Tooltip("剑回音效")] public AudioSource swordBackAudioSource;

        // 位移特效
        [Tooltip("位移特效")] public ParticleSystem particleSystem;
        private Handle _handle;
        private double _throwTime = 0;
        private readonly DateTime _baseTime = new DateTime(1970, 1, 1);
        private static SwordBlink _local;

        private void OnDestroy()
        {
            _local = null;
        }

        private void OnDisable()
        {
            _local = null;
        }

        private void OnEnable()
        {
            _local = this;
        }

        private void Start()
        {
            _handle = gameObject.GetComponent<Handle>();
            if (!_handle)
            {
                Debug.LogError("handle is null");
                return;
            }

            _local = this;
            // var handleEventLinker = gameObject.AddComponent<HandleEventLinker>();
            // var handleUnityEvent = new HandleEventLinker.HandleUnityEvent
            // {
            //     handleEvent = HandleEventLinker.HandleEvent.ItemOnlyOnThrow,
            //     side = handleSide == Side.Right
            //         ? HandleEventLinker.InteractorSide.Right
            //         : HandleEventLinker.InteractorSide.Left,
            //     onActivate = new UnityEvent<Handle>()
            // };

            // handleUnityEvent.onActivate.AddListener(a => OnThrow());
            // handleEventLinker.handleEvents.Add(handleUnityEvent);

            // handleEventLinker.CheckConfiguredEvents();
            // handleEventLinker.HandleEventActivate(HandleEventLinker.HandleEvent.OnLinkerStart, new Side?());
            _handle.item.OnFlyStartEvent += OnThrow;
            var controlEventLinker = gameObject.AddComponent<ControlEventLinker>();
            var controlUnityEvent = new ControlEventLinker.ControlUnityEvent
            {
                controlEvent = handleSide == Side.Right
                    ? ControlEventLinker.ControlEvent.RightHandGripPress
                    : ControlEventLinker.ControlEvent.LeftHandGripPress,
                onActivate = new UnityEvent()
            };
            controlUnityEvent.onActivate.AddListener(Billing);
            controlEventLinker.controlEvents.Add(controlUnityEvent);

            controlEventLinker.CheckConfiguredEvents();
            // handleEventLinker.handle = _handle;
            controlEventLinker.ControlEventActivate(ControlEventLinker.ControlEvent.OnLinkerStart);
        }

        public void OnThrow(Item item)
        {
            _local = this;
            _throwTime = (DateTime.UtcNow - _baseTime).TotalMilliseconds;
        }

        public void Billing()
        {
            if (!_local)
            {
                _local = this;
            }

            if (!Player.local || _local != this || _handle.IsHanded())
            {
                return;
            }

            if (PlayerControl.GetHand(handleSide).usePressed)
            {
                if (swordBackAudioSource)
                {
                    swordBackAudioSource.Play();
                }

                ForcePlayerGrab();
                return;
            }

            var timeNow = (DateTime.UtcNow - _baseTime).TotalMilliseconds;
            if (timeNow - _throwTime >= 3000)
            {
                return;
            }

            var itemPosition = gameObject.transform.position;
            Player.local.gameObject.transform.position = itemPosition;
            if (blinkAudioSource)
            {
                blinkAudioSource.Play();
            }

            if (particleSystem)
            {
                particleSystem.Play();
            }

            ForcePlayerGrab();

            // 失重
            MakeWeightless();
        }

        // 调用这个方法来使人物失重
        public void MakeWeightless()
        {
            var rb = Player.local.GetComponent<Rigidbody>();
            if (!rb) return;
            // 设置重力缩放为0，使物体失重
            if (rb.useGravity)
            {
                rb.useGravity = false;
            }
            else
            {
                CancelInvoke(nameof(RestoreGravity));
            }

            // 1秒后恢复重量
            Invoke(nameof(RestoreGravity), 1.5f);
        }

        // 这个方法用于恢复物体的重力
        private void RestoreGravity()
        {
            var rb = Player.local.GetComponent<Rigidbody>();
            if (!rb) return;
            rb.useGravity = true;
        }

        public void ForcePlayerGrab()
        {
            if (!_handle)
            {
                Debug.LogError("handle is null");
                Debug.LogError(GetComponent<Item>());
                return;
            }

            if (!(bool)(UnityEngine.Object)Player.local)
                return;
            var playerHand = handleSide == Side.Right
                ? Player.local.handRight
                : Player.local.handLeft;
            if (!(bool)(UnityEngine.Object)playerHand || !(bool)(UnityEngine.Object)playerHand.ragdollHand)
                return;
            if (playerHand.ragdollHand.grabbedHandle)
            {
                playerHand.ragdollHand.UnGrab(false);
            }

            // 先移回来
            _handle.item.transform.position =
                Player.local.head.transform.position + Player.local.head.transform.forward;
            playerHand.ragdollHand.Grab(_handle);
        }
    }
}